<?php
/**
 * Created by PhpStorm
 * User: huangjiacheng
 * Date: 2025/8/11
 * Time: 16:46
 */

namespace app\command;


use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\facade\Db;

class EthTrade extends Command
{
    protected function configure()
    {
        $this->setName('eth:trade')
            ->addOption('config', null, Option::VALUE_REQUIRED, '')
            ->setDescription('ETH自动交易系统');
    }
    protected $myConfig = [
        'config' => [
            'qywx' => 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=939f92b4-0fc7-4d93-bc4e-19abaec4e172',
            'buy_limit'   => 1200,   //每次购买
            'feilv' => 0.001,       //费率0.1% 买卖都需要扣
            'earn_rate' => 1.012,   //每次挂单
            'limit_max_num' => 14,       //限制次数
            'limit_middlle_num' => 9,       //限制次数
            'limit_min_num' => 3,       //限制次数
            'max_buy_price' => 100000, //
        ],
     ];
    protected function execute(Input $input, Output $output)
    {
            $data = $this->getData();
            $sql = "select * from zj_info where id=3 ";
            $list = Db::query($sql);
            $info =  $list[0];
            $sql = "select * from eth_trade_code where sell_date is null  ";
            $sellList = Db::query($sql);
            $lastData = $data[1];
            $sellNum = 0;
            $maxBuyPrice = $this->myConfig['config']['max_buy_price'];
            $minBuyPrice = $this->myConfig['config']['max_buy_price'];
            if (!empty($sellList)){
                $sellNum = count($sellList); // 已购数量
                $buyPriceArr = array_column($sellList,'buy');
                $maxBuyPrice = max($buyPriceArr); //已成交最大购入价格
                $minBuyPrice = min($buyPriceArr); //已成交最小购入价格
            }

            for ($i = 0; $i < count($data); $i++) {
                if ($i >= 1) {
                    if ((($data[$i - 1]['zzf'] == 0) && ($data[$i]['zzf'] > 0)) && ($data[$i]['cje'] / $data[$i - 1]['cje'] > 3)) {
                        if ($info['yuer'] >= $this->myConfig['config']['buy_limit']) { //余额充足
                            if (($data[$i]['open'] <= $minBuyPrice) && ($sellNum <= $this->myConfig['config']['limit_max_num'])) {
                                $flag = $this->checkInGird($data[$i],$sellList);
                                if ($flag) exit();
                                $info['yuer'] = $info['yuer'] - $this->myConfig['config']['buy_limit'];
                                $insert = "insert into eth_trade_code(`buy`,`buy_num`,`sell`,`cur_price`,`yingkui`,`buy_date`) values (
                            '".$data[$i]['open']."' ,'".($this->myConfig['config']['buy_limit']*0.999/$data[$i]['open'])."'   ,'".( $data[$i]['open'] * $this->myConfig['config']['earn_rate'])."'   ,'". $data[$i]['open']."'   ,'0'   ,'".$data[$i]['date']."' )";
                                Db::query($insert);
                              
                                $update = "update zj_info set yuer=". $info['yuer']." where id=".$info['id'];
                                Db::query($update);
                                $msg = "【买单提醒】\n购买时间：".$data[$i]['date']."\n购买价格：".$data[$i]['open']."\n"."卖出价格：".$data[$i]['open'] * $this->myConfig['config']['earn_rate']."\n购买数量：". $this->myConfig['config']['buy_limit']*0.999/$data[$i]['open']."\n";
                                $this->total($data[1], $msg);
                            }else if ( ($data[$i]['open'] <= $maxBuyPrice) && ($sellNum <= $this->myConfig['config']['limit_middlle_num'])){
                                $flag = $this->checkInGird($data[$i],$sellList);
                                if ($flag) exit();
                                $info['yuer'] = $info['yuer'] - $this->myConfig['config']['buy_limit'];
                                $insert = "insert into eth_trade_code(`buy`,`buy_num`,`sell`,`cur_price`,`yingkui`,`buy_date`) values (
                            '".$data[$i]['open']."' ,'".($this->myConfig['config']['buy_limit']*0.999/$data[$i]['open'])."'   ,'".( $data[$i]['open'] * $this->myConfig['config']['earn_rate'])."'   ,'". $data[$i]['open']."'   ,'0'   ,'".$data[$i]['date']."' )";
                                Db::query($insert);
                              
                                $update = "update zj_info set yuer=". $info['yuer']." where id=".$info['id'];
                                Db::query($update);
                                $msg = "【买单提醒】\n购买时间：".$data[$i]['date']."\n购买价格：".$data[$i]['open']."\n"."卖出价格：".$data[$i]['open'] * $this->myConfig['config']['earn_rate']."\n购买数量：". $this->myConfig['config']['buy_limit']*0.999/$data[$i]['open']."\n";
                                $this->total($data[1], $msg);
                            }elseif(($data[$i]['open'] >= $maxBuyPrice)&& ($sellNum <= $this->myConfig['config']['limit_min_num'])){
                                $flag = $this->checkInGird($data[$i],$sellList);
                                if ($flag) exit();
                                $info['yuer'] = $info['yuer'] - $this->myConfig['config']['buy_limit'];
                                $insert = "insert into eth_trade_code(`buy`,`buy_num`,`sell`,`cur_price`,`yingkui`,`buy_date`) values (
                            '".$data[$i]['open']."' ,'".($this->myConfig['config']['buy_limit']*0.999/$data[$i]['open'])."'   ,'".( $data[$i]['open'] * $this->myConfig['config']['earn_rate'])."'   ,'". $data[$i]['open']."'   ,'0'   ,'".$data[$i]['date']."' )";
                                Db::query($insert);
                            
                                $update = "update zj_info set yuer=". $info['yuer']." where id=".$info['id'];
                                Db::query($update);
                                $msg = "【买单提醒】\n购买时间：".$data[$i]['date']."\n购买价格：".$data[$i]['open']."\n"."卖出价格：".$data[$i]['open'] * $this->myConfig['config']['earn_rate']."\n购买数量：". $this->myConfig['config']['buy_limit']*0.999/$data[$i]['open']."\n";                               
                                $this->total($data[1],$msg);
                            }else{
                                $this->alarm("【仓位过重，且成交上限上浮】\n");
                            }
                        }else{
                            $this->alarm("【余额不足警告】\n");
                        }
                    }
                }
            }

            if (!empty($sellList)) {
                foreach ($sellList as $sell) {
                    if ($sell['sell'] <= $data[1]['high'] && ($sell['buy_date'] < $data[1]['date']) ) {
                        $sql = "select * from zj_info where id=3 ";
                        $list = Db::query($sql);
                        $info =  $list[0];
                        //$this->alarm("【卖单提醒】\n成交时间：".$data[1]['date']."\n"."卖出价格：".$sell['sell']."\n卖出数量：". $sell['buy_num']."\n");
                        $yuer = $info['yuer']+($sell['sell']*$sell['buy_num']*0.999);
                        $update = "update eth_trade_code set sell_date='". $data[1]['date']."' where id=".$sell['id'];
                        Db::query($update);
                        $update = "update zj_info set yuer='". $yuer."' where id=".$info['id'];
                        Db::query($update);
                        $this->total($data[1],'');
                        continue;
                    }
                }
            }
            $currentMinute = date('i');

// 判断是否是10分钟的倍数（0分、10分、20分、30分、40分、50分）
        if ($currentMinute % 30 == 0) {
            // 执行任务
                  $this->total($data[1],'');
        }

          

    }
    public function getData(){
        $data = [];
        $curl = curl_init();

        curl_setopt_array($curl, [
            CURLOPT_URL => "http://data-api.binance.vision/api/v3/klines?symbol=ETHUSDT&interval=1m&limit=3",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_POSTFIELDS => "",
            CURLOPT_HTTPHEADER => [
                "content-type: application/json"
            ],
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);
        if ($err) {
            echo "cURL Error #:" . $err;
            $data = [];
        } else {
            /*
            [
               1499040000000,      // 开盘时间
               "0.01634790",       // 开盘价
               "0.80000000",       // 最高价
               "0.01575800",       // 最低价
               "0.01577100",       // 收盘价(当前K线未结束的即为最新价)
               "148976.11427815",  // 成交量
               1499644799999,      // 收盘时间
               "2434.19055334",    // 成交额
               308,                // 成交笔数
               "1756.87402397",    // 主动买入成交量
               "28.46694368",      // 主动买入成交额
               "17928899.62484339" // 请忽略该参数
             ]
            * */
            $responseData = json_decode($response, true);
            $data = [];
            foreach ($responseData as $item) {
                $tmp = [
                    'date' => date("Y-m-d H:i:s", $item[0] / 1000),
                    'open' => $item[1],
                    'high' => $item[2],
                    'low' => $item[3],
                    'close' => $item[4],
                    'zf' => round((100 * (floatval($item[2]) - floatval($item[3])) / floatval($item[1])), 3),
                    'zzf' => round((100 * (floatval($item[2]) - floatval($item[1])) / floatval($item[1])), 3),
                    'fzf' => round((100 * (floatval($item[1]) - floatval($item[3])) / floatval($item[1])), 3),
                    'cje' => intval($item[7]),
                ];
                $data[] = $tmp;
                $insert = "replace into eth_base_info(`date`,`open`,`high`,`low`,`close`,`zf`,`zzf`,`fzf`,`cje`) values (
                         '".$tmp['date']."' ,'".$tmp['open']."'   ,'".$tmp['high']."'   ,'".$tmp['low']."'   ,'".$tmp['close']."'   ,'".$tmp['zf']."'   
                         ,'".$tmp['zzf']."'   ,'".$tmp['fzf']."'   ,'".$tmp['cje']."' )";
                Db::query($insert);
            }
            $newData = [];
            $newData[] = $data[0];
            $newData[] = $data[1];
            $data = $newData;
        }
        return $data;
    }
    protected function alarm($msg){
        $webhook = $this->myConfig['config']['qywx'];
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $webhook);
        curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,false);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_HTTPHEADER,array('Content-Type: application/json;charset=utf-8'));
        $post_data = [
            'msgtype' => 'text',
            'text' => [
                'content' => "【".date("Y-m-d H:i:s")."】\n".$msg,
            ]
        ];
        $post_data = json_encode($post_data);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
        $data = curl_exec($curl);
        curl_close($curl);
    }

    public function total($data,$msg_old){
        $sql = "select * from zj_info where id=3 ";
        $list = Db::query($sql);
        $info =  $list[0];
        $sql = "select * from eth_trade_code where sell_date is null  ";
        $sellList = Db::query($sql);
        if (!empty($sellList)){
            $shizhi = $info['yuer'];
            $close = $data['close'];
            foreach ($sellList as $sell) {
                $shizhi+=($sell['buy_num']*$close);
            }
            $msg = "【账号概览】\n"."总市值：".$shizhi."\n可用余额：".$info['yuer'];
            $msg.="\n盈亏：".round((100*($shizhi-$info['bj'])/$info['bj']),3)."%";
            $msg.="\n当前价格：".$close;
            $msg.="\n【明细如下】";
            foreach ($sellList as $sell) {
                $msg.= "\n【".$sell['buy_date']."】【".round($sell['buy'],2)."】【".round($sell['sell'],2)."】【".round((100*($close-$sell['buy'])/$sell['buy']),3)."%】";
            }
            $this->alarm($msg_old."\n".$msg);
        }else{
             $shizhi = $info['yuer'];
            $close = $data['close'];
             $msg = "【账号概览】\n"."总市值：".$shizhi."\n可用余额：".$info['yuer'];
            $msg.="\n盈亏：".round((100*($shizhi-$info['bj'])/$info['bj']),3)."%";
            $msg.="\n当前价格：".$close;
                $this->alarm($msg_old."\n".$msg);
        }

    }
    public function checkInGird($lastData,$sellList){
        $flag = false;
        foreach ($sellList as $row){
            $abs = abs(round(($lastData['open'] - $row['buy'])/$row['buy'],2));
            if ($abs <= 0.0075){
                $flag = true;
                $this->alarm("【已存在网格区间内】\n【".$abs."】【".$lastData['open']."】【".$row['buy']."】");
                break;
            }
        }
        return $flag ;
    }
}